﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace YArchitech.Controls
{
	public class DataGridViewGroupCell : DataGridViewTextBoxCell
	{
		public int PlusWidth
		{
			get
			{
				return this.PLUS_WIDTH;
			}
			set
			{
				this.PLUS_WIDTH = value;
			}
		}

		public DataGridViewGroupCell()
		{
			this.groupLevel = 1;
		}

		public int GroupLevel
		{
			get
			{
				return this.groupLevel;
			}
			set
			{
				this.groupLevel = value;
			}
		}

		public DataGridViewGroupCell ParentCell
		{
			get
			{
				return this.parentCell;
			}
		}

		public bool Collapsed
		{
			get
			{
				return this.collapsed;
			}
		}

		public DataGridViewGroupCell[] ChildCells
		{
			get
			{
				if (this.childCells == null)
				{
					return null;
				}
				return this.childCells.ToArray();
			}
		}

		public System.Drawing.Rectangle GroupPlusRect
		{
			get
			{
				return this.groupPlusRect;
			}
		}

		public bool BPaint
		{
			get
			{
				return this.bPaint;
			}
			set
			{
				this.bPaint = value;
			}
		}

		public int AddChildCell(DataGridViewGroupCell cell)
		{
			return this.AddChildCellRange(new DataGridViewGroupCell[]
			{
				cell
			});
		}

		public int AddChildCellRange(DataGridViewGroupCell[] cells)
		{
			bool flag = false;
			if (this.childCells == null)
			{
				this.childCells = new List<DataGridViewGroupCell>();
				flag = true;
			}
			foreach (DataGridViewGroupCell dataGridViewGroupCell in cells)
			{
				this.childCells.Add(dataGridViewGroupCell);
				dataGridViewGroupCell.groupLevel = this.groupLevel + 1;
				dataGridViewGroupCell.PlusWidth = 10;
			}
			if (flag)
			{
				base.DataGridView.InvalidateCell(this);
			}
			return this.childCells.Count;
		}

		public int AddChildCellRange(List<DataGridViewGroupCell> cells)
		{
			bool flag = false;
			if (this.childCells == null)
			{
				this.childCells = new List<DataGridViewGroupCell>();
				flag = true;
			}
			foreach (DataGridViewGroupCell dataGridViewGroupCell in cells)
			{
				this.childCells.Add(dataGridViewGroupCell);
				dataGridViewGroupCell.groupLevel = this.groupLevel + 1;
				dataGridViewGroupCell.PlusWidth = 10;
			}
			if (flag)
			{
				base.DataGridView.InvalidateCell(this);
			}
			return this.childCells.Count;
		}

		protected override void Paint(Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
		{
			if (!this.bPaint)
			{
				base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
				return;
			}
			Pen pen = new Pen(base.DataGridView.GridColor);
			Brush brush = new SolidBrush(cellStyle.BackColor);
			int num = this.groupLevel * this.PlusWidth;
			System.Drawing.Rectangle rectLeft = new System.Drawing.Rectangle(cellBounds.Left, cellBounds.Top - 1, num, cellBounds.Height);
			cellBounds.X += num;
			cellBounds.Width -= num;
			base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
			this.PaintGroupPlus(graphics, pen, brush, cellStyle, rectLeft, this.collapsed);
			pen.Dispose();
			brush.Dispose();
		}

		private void PaintGroupPlus(Graphics graphics, Pen gridPen, Brush bruBK, DataGridViewCellStyle cellStyle, System.Drawing.Rectangle rectLeft, bool collapsed)
		{
			graphics.FillRectangle(bruBK, rectLeft);
			int num = rectLeft.Left + (this.groupLevel - 1) * this.PlusWidth;
			graphics.DrawLine(gridPen, num, rectLeft.Top, num, rectLeft.Bottom);
			graphics.DrawLine(gridPen, num, rectLeft.Top, rectLeft.Right, rectLeft.Top);
			graphics.DrawLine(gridPen, rectLeft.Right, rectLeft.Top, rectLeft.Right, rectLeft.Bottom);
			graphics.DrawLine(gridPen, rectLeft.Left, rectLeft.Top, rectLeft.Left, rectLeft.Bottom);
			bool flag = false;
			for (int i = 1; i < this.groupLevel; i++)
			{
				graphics.DrawLine(gridPen, rectLeft.Left + i * this.PlusWidth, rectLeft.Top, rectLeft.Left + i * this.PlusWidth, rectLeft.Bottom);
				if (!flag && this.IsLastCell(i))
				{
					graphics.DrawLine(gridPen, rectLeft.Left + (i - 1) * this.PlusWidth, rectLeft.Bottom, rectLeft.Left + this.groupLevel * this.PlusWidth, rectLeft.Bottom);
					flag = true;
				}
			}
			if (this.childCells != null && this.childCells.Count > 0)
			{
				this.groupPlusRect = new System.Drawing.Rectangle((this.groupLevel - 1) * this.PlusWidth + rectLeft.Left + (this.PlusWidth - 12) / 2, rectLeft.Top + (rectLeft.Height - 12) / 2, 12, 12);
				graphics.DrawRectangle(gridPen, this.groupPlusRect);
				graphics.DrawLine(Pens.Black, this.groupPlusRect.Left + 3, this.groupPlusRect.Top + this.groupPlusRect.Height / 2, this.groupPlusRect.Right - 3, this.groupPlusRect.Top + this.groupPlusRect.Height / 2);
				if (collapsed)
				{
					graphics.DrawLine(Pens.Black, this.groupPlusRect.Left + this.groupPlusRect.Width / 2, this.groupPlusRect.Top + 3, this.groupPlusRect.Left + this.groupPlusRect.Width / 2, this.groupPlusRect.Bottom - 3);
				}
			}
		}

		private bool IsLastCell(int level)
		{
			int nextRow = base.DataGridView.Rows.GetNextRow(base.RowIndex, DataGridViewElementStates.None);
			return nextRow == -1 || (base.DataGridView.Rows[nextRow].Cells[0] as DataGridViewGroupCell).GroupLevel == level;
		}

		protected override void OnMouseDown(DataGridViewCellMouseEventArgs e)
		{
			System.Drawing.Rectangle cellDisplayRectangle = base.DataGridView.GetCellDisplayRectangle(base.ColumnIndex, base.RowIndex, false);
			System.Drawing.Point pt = new System.Drawing.Point(cellDisplayRectangle.Left + e.Location.X, cellDisplayRectangle.Top + e.Location.Y);
			if (this.groupPlusRect.Contains(pt))
			{
				if (this.collapsed)
				{
					this.Expand();
				}
				else
				{
					this.Collapse();
				}
			}
			base.OnMouseDown(e);
		}

		public void Expand()
		{
			this.collapsed = false;
			this.ShowChild(true);
			base.DataGridView.InvalidateCell(this);
		}

		private void ShowChild(bool show)
		{
			if (this.childCells == null)
			{
				return;
			}
			foreach (DataGridViewGroupCell dataGridViewGroupCell in this.childCells)
			{
				if (dataGridViewGroupCell.RowIndex != -1)
				{
					base.DataGridView.Rows[dataGridViewGroupCell.RowIndex].Visible = show;
					if (!dataGridViewGroupCell.collapsed)
					{
						dataGridViewGroupCell.ShowChild(show);
					}
				}
			}
		}

		public void Collapse()
		{
			this.collapsed = true;
			this.ShowChild(false);
			base.DataGridView.InvalidateCell(this);
		}

		public void ExpandAll()
		{
			if (this.childCells == null)
			{
				return;
			}
			foreach (DataGridViewGroupCell dataGridViewGroupCell in this.childCells)
			{
				dataGridViewGroupCell.Expand();
				dataGridViewGroupCell.ExpandAll();
			}
		}

		private int PLUS_WIDTH = 20;

		private System.Drawing.Rectangle groupPlusRect;

		private int groupLevel;

		private DataGridViewGroupCell parentCell;

		private bool collapsed;

		private List<DataGridViewGroupCell> childCells;

		private bool bPaint = true;
	}
}
